#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>

#include <htslib/bgzf.h>
#include <htslib/sam.h>

#define read_len 150

int usage()
{
    fprintf(stderr,"bamSample [option] <in.bam>  <prefix> <bed>\n");
    fprintf(stderr,"-f STR reference filename\n");
    return -1;
}

struct dot{
	int flag;
	int tid;
	int pos;
	char baminfo[10000];
	
};


int get_rand(int *a, int m, int n, int k)
{
    int i,j,t;
    for(i=0; i<k;)
    {
        t=rand()%(n-m+1)+m;
        for(j=0;j<i;j++)
            if(a[j]==t) break;
        if(j==i)
            a[i++]=t;
    }
        return 0;
}

int get_next_rand(int *a, int m, int n, int k)
{
        int i;
        for(i=0;i<k;i++)
        {
                if(a[i]<n)
                        a[i]=a[i]+1;
                else
                        a[i]=0;
        }
        return 0;
}



int main( int argc , char *argv[])
{

	int i,c;

//	samFile *fp = NULL ;
	BGZF *fp =NULL;
	bam_hdr_t  *h = NULL ;
	bam1_t *b = NULL ;

   	int total_reads_num=0;
	
	int out_depth=50;
	int in_depth=250;
	int expect=9;
	int expect_test=1;

	while( (c = getopt(argc,argv,"d:D:")) >=0 ){
		switch(c){
			case 'd':  in_depth = atoi(optarg);  break ;
            		case 'D':  out_depth = atoi(optarg); break ;
	    	default:
		printf("unKnow  argument\n");
		return -1;
		}	
    	}

    if( optind + 3 !=  argc)
	return usage();

//        expect_test = out_depth*120/(in_depth);
	expect_test = out_depth;
	int min=0;
	int max_test = in_depth-1;	

//	printf("%d\n", expect_test);

//    fp = sam_open(argv[optind],"r");
 	fp = bgzf_open( argv[optind], "r");
//    h = sam_hdr_read(fp);
	h = bam_hdr_read(fp);
//    hts_set_threads(fp,n_threads);
    	b = bam_init1();

//	samFile *fp_test[10];
	BGZF *fp_test[50];
	char project[100];
        strcpy(project,argv[optind+1] );
        char test_Tbam[100][100];
	
	int test_rand[2000];
	char shell[1000];

	for(i=0;i<50;i++)
        {
                fp_test[i] = NULL ;
		sprintf(test_Tbam[i],"%s.%d.train.%d.bam" ,project,out_depth,i);
//                fp_test[i] = sam_open( test_Tbam[i],"w");
		fp_test[i] = bgzf_open( test_Tbam[i],"w");
//		sam_hdr_write(fp_test[i], h);
		bam_hdr_write(fp_test[i], h );
        }
	
	FILE *fp_bed;
	fp_bed=fopen(argv[optind+2], "r");
	char bed_chr[10];
	int bed_chr_tid;
	int bed_pos;
	int bed_depth;
	int bam_read_en=bam_read1(fp,b);

	fscanf(fp_bed,"%s\t%d\t%*[^\n]\n", bed_chr, &bed_pos  );
	if(strcmp(bed_chr,"X")==0)
                bed_chr_tid=23;
        else if(strcmp(bed_chr,"Y")==0)
                bed_chr_tid=24;
        else if(strcmp(bed_chr,"M")==0)
                bed_chr_tid=22;
        else    bed_chr_tid=atoi(bed_chr)-1;

	int 	train_w_en=0;
	int 	test_w_en=0;

	get_rand( test_rand, min, max_test, expect_test);


   while(bam_read_en >= 0 &&  !feof(fp_bed))
   {	

//	printf("%d\t%d\t%d\t%d\n", bed_chr_tid,bed_pos ,b->core.tid, b->core.pos);
	if (b->core.tid==bed_chr_tid && b->core.pos>=bed_pos-read_len && b->core.pos<=bed_pos+read_len)
	{
		total_reads_num++;
		get_rand( test_rand, min, max_test, expect_test);
//		get_next_rand( test_rand, min, max_test, expect_test);
//		printf("%d\n", test_rand[1] );
		for(i=0; i<expect_test; i++)
              	{
			if(test_rand[i]<50)
//			printf("%d\t", test_rand[i]);
	                        test_w_en=bam_write1(fp_test[test_rand[i]],  b);
               	}
//		printf("\n");
		bam_read_en=bam_read1(fp,b);
	}
	else if(b->core.tid<bed_chr_tid || (b->core.tid<=bed_chr_tid && b->core.pos<bed_pos-read_len))
	{
		bam_read_en=bam_read1(fp,b);
	}
	else
	{
		fscanf(fp_bed,"%s\t%d\t%*[^\n]\n", bed_chr, &bed_pos );
		if(strcmp(bed_chr,"X")==0)
	                bed_chr_tid=23;
        	else if(strcmp(bed_chr,"Y")==0)
                	bed_chr_tid=24;
	        else if(strcmp(bed_chr,"M")==0)
        	        bed_chr_tid=22;
	        else    bed_chr_tid=atoi(bed_chr)-1;
	}

    }

//    printf("%d\n", total_reads_num );   
	for(i=0;i<50;i++)
		bgzf_close(fp_test[i]);
    bgzf_close(fp);
    bam_hdr_destroy(h);
    bam_destroy1(b);
    return 0 ;
}
